#include "stdafx.h"
#include "Entity.h"

#include "IComponent.h"

using namespace std;

namespace ZeEngine
{
	u64 Entity::m_currentID = 0;

    Entity::Entity(const std::string& name) : m_attachedComponents(0), m_name(name), m_fRemove(false)
	{
		m_id = m_currentID++;
		m_fActive = true;
		m_components.resize(10);
        m_index = -1;
	}

	Entity::~Entity()
	{
		m_components.clear();
		m_attachedComponents = 0;
        m_fRemove = true;
	}

    IComponent* Entity::AddComponent(std::unique_ptr<IComponent> pComponent)
	{
		if (pComponent->GetIndex() >= static_cast<s32>(m_components.size()))
		{
			m_components.resize(m_components.size() * 2);
		}

        pComponent->m_pParent = this;
        m_attachedComponents |= pComponent->GetType();
        u32 index = pComponent->GetIndex();

		m_components[pComponent->GetIndex()] = move(pComponent);

        return m_components[index].get();
	}

    void Entity::RemoveComponent(IComponent& component)
	{
        m_attachedComponents ^= component.GetType();
        m_components[component.GetIndex()].release();
	}

	void Entity::RemoveAllComponents()
	{	
		m_components.clear();
		m_components.resize(10);
	}

	bool Entity::SupportsAllComponents(u64 componentMask) const
	{
		return (m_attachedComponents & componentMask) == componentMask;
	}

	bool Entity::SupportsAtLeastOneComponent(u64 componentMask) const
	{
		return (m_attachedComponents & componentMask) != 0;
	}

	u64 Entity::GetID() const
	{
		return m_id;
	}

	const string& Entity::GetName() const
	{
		return m_name;
	}

	void Entity::SetActive(bool fActive)
	{
        m_fActive = fActive;
		for (auto& pComponent : m_components)
		{           
            if (pComponent)
                pComponent->SetActive(fActive);
		}
	}

	void Entity::Clear(const std::string& name)
	{
        m_fActive = true;
        m_fRemove = false;

		RemoveAllComponents();
		m_attachedComponents = 0;
		m_name = name;
	}
}
